package top.heliming.youyou.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import top.heliming.youyou.common.utils.CookieUtils;
import top.heliming.youyou.config.FilterProperties;
import top.heliming.youyou.config.JwtProperties;
import top.heliming.youyou.util.JwtUtils;

/***
 * description
 * @author heliming
 * @date 2019/6/9 0009 下午 5:42
 **/
@Slf4j
@Component
@EnableConfigurationProperties({JwtProperties.class, FilterProperties.class})
public class LoginFilter extends ZuulFilter {

  @Autowired
  private JwtProperties properties;

  @Autowired
  private FilterProperties filterProp;

  @Override
  public String filterType() {
    return "pre";
  }

  @Override
  public int filterOrder() {
    return 5;
  }

  @Override
  public boolean shouldFilter() {
    // 获取上下文
    RequestContext ctx = RequestContext.getCurrentContext();
    // 获取request
    HttpServletRequest req = ctx.getRequest();
    // 获取路径
    String requestURI = req.getRequestURI();
    // 判断白名单
    return !isAllowPath(requestURI);
  }

  private boolean isAllowPath(String requestURI) {
    // 定义一个标记
    boolean flag = false;
    // 遍历允许访问的路径
    for (String path : this.filterProp.getAllowPaths()) {
      // 然后判断是否是符合
      if(requestURI.startsWith(path)){
        flag = true;
        break;
      }
    }
    return flag;
  }

  @Override
  public Object run() {
    //获取上下文
    RequestContext context = RequestContext.getCurrentContext();
    // 获取request
    HttpServletRequest request = context.getRequest();
    // 获取token
    String token = CookieUtils.getCookieValue(request, this.properties.getCookieName());
    // 校验
    try {
      //从Token获取解析用户信息
      JwtUtils.getUserInfo(this.properties.getPublicKey(), token);
      //解析成功，什么都不做，放行

      //todo 如果做权限管理的话，在这做权限检验
    } catch (Exception e) {
      //检验出现异常，返回403
      context.setSendZuulResponse(false);
      context.setResponseStatusCode(403);
      log.error("非法访问，未登录，地址：{}", request.getRemoteHost(), e);
    }
    return null;
  }
}
